package com.newshub.admin.service.impl;

import com.newshub.common.fetch.FetchedNews;
import com.newshub.common.fetch.RssParseResult;
import com.newshub.admin.entity.RssFeed;
import com.newshub.admin.service.RssParseService;
import com.newshub.logging.annotation.BusinessLog;
import com.newshub.logging.annotation.LogLevel;
import com.rometools.rome.feed.synd.SyndEntry;
import com.rometools.rome.feed.synd.SyndFeed;
import com.rometools.rome.io.SyndFeedInput;
import com.rometools.rome.io.XmlReader;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * RSS解析服务实现
 * 使用Rome库解析RSS/Atom格式
 */
@Slf4j
@Service
public class RssParseServiceImpl implements RssParseService {
    
    @Override
    @BusinessLog(module = "RSS解析管理", description = "解析RSS源", level = LogLevel.INFO)
    public RssParseResult parseRssFeed(RssFeed rssFeed) {
        try {
            log.info("开始解析RSS源: {} ({})", rssFeed.getName(), rssFeed.getUrl());
            return parseRssUrl(rssFeed.getUrl());
        } catch (Exception e) {
            log.error("解析RSS源失败: {} - {}", rssFeed.getName(), e.getMessage(), e);
            throw new RuntimeException("解析RSS源失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    @BusinessLog(module = "RSS解析管理", description = "解析RSS URL", level = LogLevel.INFO)
    public RssParseResult parseRssUrl(String url) {
        try {
            log.info("开始解析RSS URL: {}", url);
            
            // 建立连接以获取HTTP状态码和响应大小（若可用）
            URL u = URI.create(url).toURL();
            URLConnection conn = u.openConnection();
            conn.setConnectTimeout(20000);  // 连接超时：20秒
            conn.setReadTimeout(30000);     // 读取超时：30秒
            long responseSize = conn.getContentLengthLong();

            // 使用Rome库解析RSS
            SyndFeedInput input = new SyndFeedInput();
            SyndFeed feed = input.build(new XmlReader(conn.getInputStream()));
            
            log.info("RSS解析成功，标题: {}, 条目数: {}", feed.getTitle(), feed.getEntries().size());
            
            List<FetchedNews> newsList = new ArrayList<>();
            
            for (SyndEntry entry : feed.getEntries()) {
                FetchedNews news = convertToFetchedNews(entry);
                newsList.add(news);
            }
            
            log.info("RSS解析完成，转换新闻数: {}", newsList.size());
            Integer httpStatusCode = null;
            try {
                // 仅在HTTP协议下尝试获取状态码
                if (conn instanceof java.net.HttpURLConnection httpConn) {
                    httpStatusCode = httpConn.getResponseCode();
                }
            } catch (Exception ignore) {
            }

            return RssParseResult.builder()
                    .httpStatusCode(httpStatusCode)
                    .responseSize(responseSize >= 0 ? responseSize : null)
                    .entries(newsList)
                    .build();
            
        } catch (Exception e) {
            log.error("解析RSS URL失败: {} - {}", url, e.getMessage(), e);
            throw new RuntimeException("解析RSS URL失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 将SyndEntry转换为FetchedNews
     */
    private FetchedNews convertToFetchedNews(SyndEntry entry) {
        // 生成外部唯一标识（用于去重）
        String externalId = generateExternalId(entry);
        
        // 转换发布时间
        LocalDateTime publishTime = null;
        if (entry.getPublishedDate() != null) {
            publishTime = entry.getPublishedDate().toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDateTime();
        }
        
        // 提取图片链接
        String imageUrl = extractImageUrl(entry);
        
        return FetchedNews.builder()
                .title(entry.getTitle())
                .summary(entry.getDescription() != null ? entry.getDescription().getValue() : null)
                .content(entry.getContents() != null && !entry.getContents().isEmpty() 
                        ? entry.getContents().get(0).getValue() : null)
                .url(entry.getLink())
                .imageUrl(imageUrl)
                .publishTime(publishTime)
                .author(entry.getAuthor())
                .externalId(externalId)
                .category(entry.getCategories() != null && !entry.getCategories().isEmpty() 
                        ? entry.getCategories().get(0).getName() : null)
                .source(entry.getSource() != null ? entry.getSource().getTitle() : null)
                .build();
    }
    
    /**
     * 生成外部唯一标识
     * 优先使用GUID，如果没有则使用URL的MD5
     */
    private String generateExternalId(SyndEntry entry) {
        // 优先使用GUID
        if (entry.getUri() != null && !entry.getUri().trim().isEmpty()) {
            return entry.getUri();
        }
        
        // 如果没有GUID，使用URL的MD5
        if (entry.getLink() != null && !entry.getLink().trim().isEmpty()) {
            try {
                return java.security.MessageDigest.getInstance("MD5")
                        .digest(entry.getLink().getBytes())
                        .toString();
            } catch (java.security.NoSuchAlgorithmException e) {
                log.warn("MD5算法不可用，使用UUID作为备选: {}", e.getMessage());
            }
        }
        
        // 最后使用UUID
        return UUID.randomUUID().toString();
    }
    
    /**
     * 提取图片链接
     * 从RSS条目的各种可能位置提取图片URL
     */
    private String extractImageUrl(SyndEntry entry) {
        // 1. 检查是否有媒体内容
        if (entry.getForeignMarkup() != null) {
            for (Object markup : entry.getForeignMarkup()) {
                if (markup instanceof String) {
                    String markupStr = (String) markup;
                    // 简单的图片标签提取
                    if (markupStr.contains("<img") && markupStr.contains("src=")) {
                        int srcIndex = markupStr.indexOf("src=\"");
                        if (srcIndex != -1) {
                            int startIndex = srcIndex + 5;
                            int endIndex = markupStr.indexOf("\"", startIndex);
                            if (endIndex != -1) {
                                return markupStr.substring(startIndex, endIndex);
                            }
                        }
                    }
                }
            }
        }
        
        // 2. 检查描述中的图片
        if (entry.getDescription() != null && entry.getDescription().getValue() != null) {
            String description = entry.getDescription().getValue();
            if (description.contains("<img") && description.contains("src=")) {
                int srcIndex = description.indexOf("src=\"");
                if (srcIndex != -1) {
                    int startIndex = srcIndex + 5;
                    int endIndex = description.indexOf("\"", startIndex);
                    if (endIndex != -1) {
                        return description.substring(startIndex, endIndex);
                    }
                }
            }
        }
        
        return null;
    }
}
